﻿<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="model"
    targetNamespace="urn:effun-net-dycox-data-model"
    elementFormDefault="qualified"
    xmlns="urn:effun-net-dycox-data-model"
    xmlns:mstns="urn:effun-net-dycox-data-model"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
  <xs:complexType name="property">
    <xs:all>
      <xs:element name="validation" maxOccurs="1" minOccurs="0">
        <xs:complexType>
          <xs:choice minOccurs="0" maxOccurs="unbounded">
            <xs:element name="required" type="requiredValidator"></xs:element>
            <xs:element name="compare" type="compareValidator"></xs:element>
            <xs:element name="regex" type="regexValidator"></xs:element>
            <xs:element name="range" type="rangeValidator"></xs:element>
          </xs:choice>
        </xs:complexType>
      </xs:element>
      <xs:element name="customAttributes" type="customAttributes" maxOccurs="1" minOccurs="0"></xs:element>
      <xs:element name="mapping" type="propertyMapping" minOccurs="0"></xs:element>
      <xs:element name="serialization" type="propertySerializationOptions" minOccurs="0"></xs:element>
    </xs:all>
    <xs:attributeGroup ref="commonAttributes"></xs:attributeGroup>
    <xs:attribute name="visible" type="xs:boolean" default="true"></xs:attribute>
    <xs:attribute name="category" type="xs:string"></xs:attribute>
    <xs:attribute name="converter" type="xs:string"></xs:attribute>
    <xs:attribute name="format" type="xs:string"></xs:attribute>
    <xs:attribute name="defaultValue" type="xs:string"></xs:attribute>
    <xs:attribute name="canModify" type="xs:boolean" default="true"></xs:attribute>
    <xs:attribute name="readOnly" type="xs:boolean"></xs:attribute>
    <xs:attribute name="type" type="clrDataTypes"></xs:attribute>
    <xs:attribute name="modifier" type="memberInheritanceModifier"></xs:attribute>
    <xs:attribute name="changeTracking" type="changeTracking"></xs:attribute>
    <xs:attribute name="setterAccess" type="memberAccess">
      <xs:annotation>
        <xs:documentation>Not supported yet!</xs:documentation>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute name="use" default="User" type="propertyUsage">
    </xs:attribute>
    <xs:anyAttribute ></xs:anyAttribute>
  </xs:complexType>

  <xs:simpleType name="propertyUsage">
    <xs:restriction base="xs:string">
      <xs:enumeration value="User"></xs:enumeration>
      <xs:enumeration value="Key"></xs:enumeration>
      <xs:enumeration value="Application"></xs:enumeration>
      <xs:enumeration value="Control"></xs:enumeration>
      <xs:enumeration value="None"></xs:enumeration>
    </xs:restriction>
  </xs:simpleType>
  
  <xs:attributeGroup name="memberAttributes">
    <xs:attribute name="displayName" type="xs:string"></xs:attribute>
    <xs:attribute name="description" type="xs:string"></xs:attribute>
    <xs:attribute name="access" type="memberAccess"></xs:attribute>
    <xs:attribute name="browsable" type="xs:boolean" default="true"></xs:attribute>
    <xs:attribute name="doc" type="xs:string"></xs:attribute>
  </xs:attributeGroup>

  <xs:attributeGroup name="commonAttributes">
    <xs:attribute name="name" use="required" type="xs:Name">
    </xs:attribute>
    <xs:attributeGroup ref="mstns:memberAttributes"></xs:attributeGroup>
  </xs:attributeGroup>

  <xs:element name="models">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="fileOptions" minOccurs="0"></xs:element>
        <xs:element ref="model" maxOccurs="unbounded"></xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:complexType name="changeTrackingOptions">
    <xs:attribute name="mode" type="changeTracking" default="Auto"></xs:attribute>
    <xs:attribute name="dycoxChangeTracking" type="xs:boolean"></xs:attribute>
    <xs:attribute name="implemented" type="xs:boolean"></xs:attribute>
  </xs:complexType>

  <xs:complexType name="typeReference">
    <xs:attribute name="type" use="required">
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:minLength value="1"></xs:minLength>
        </xs:restriction>
      </xs:simpleType>
    </xs:attribute>
  </xs:complexType>

  <xs:complexType name="baseTypes">
    <xs:sequence>
      <xs:element name="class" minOccurs="0" maxOccurs="1" type="typeReference"></xs:element>
      <xs:element name="interface" minOccurs="0" maxOccurs="unbounded" type="typeReference"></xs:element>
    </xs:sequence>
  </xs:complexType>
  
  <xs:element name="model">
    <xs:complexType>
      <xs:all>
        <xs:element name="baseTypes" minOccurs="0" maxOccurs="1" type="baseTypes"></xs:element>
        <xs:element name="changeTracking" type="changeTrackingOptions" minOccurs="0" maxOccurs="1"></xs:element>
        <xs:element name="mapping" minOccurs="0" type="typeMapping" maxOccurs="1"></xs:element>
        <xs:element name="customAttributes" type="customAttributes" minOccurs="0" maxOccurs="1"></xs:element>
        <xs:element name="properties">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="property" type="property" minOccurs="0" maxOccurs="unbounded"></xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:all>
      <xs:attributeGroup ref="commonAttributes"></xs:attributeGroup>
      <xs:attribute name="namespace" type="xs:string"></xs:attribute>
      <xs:attribute name="isPartial" type="xs:boolean" default="true"></xs:attribute>
      <xs:attribute name="modifier" type="typeInheritanceModifier"></xs:attribute>
      <xs:attribute name="serializationEnabled" type="xs:boolean" default="true"></xs:attribute>
    </xs:complexType>
    <xs:key name="propertyNames">
      <xs:selector xpath="property"></xs:selector>
      <xs:field xpath="@name"></xs:field>
    </xs:key>
  </xs:element>

  <xs:complexType name="validator" abstract="true">
    <xs:attribute name="errorMessage" type="xs:string"></xs:attribute>
    <xs:attribute name="condition" type="xs:string">
      <xs:annotation>
        <xs:documentation>
          An C# syntax expression to specify the condition of whether to make the validation happens.
          This expression will be parsed and invoked dynamically at run-time.
          All properties within the epxression refer to an instance of current type.
        </xs:documentation>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute name="isWarning" type="xs:boolean"></xs:attribute>
  </xs:complexType>

  <xs:simpleType name="compareOperator">
    <xs:restriction base="xs:string">
      <xs:enumeration value="Equals"></xs:enumeration>
      <xs:enumeration value="NotEquals"></xs:enumeration>
      <xs:enumeration value="GreaterThan"></xs:enumeration>
      <xs:enumeration value="GreaterThanOrEquals"></xs:enumeration>
      <xs:enumeration value="LessThan"></xs:enumeration>
      <xs:enumeration value="LessThanOrEquals"></xs:enumeration>
      <xs:enumeration value="StringContains"></xs:enumeration>
      <xs:enumeration value="StringStartsWith"></xs:enumeration>
      <xs:enumeration value="StringEndsWith"></xs:enumeration>
      <xs:enumeration value="TypeEquals"></xs:enumeration>
      <xs:enumeration value="TypeCompatible"></xs:enumeration>
      <xs:enumeration value="TypeConvertible"></xs:enumeration>
      <xs:enumeration value="BitTest"></xs:enumeration>
    </xs:restriction>

  </xs:simpleType>
  
  <xs:complexType name="compareValidator">
    <xs:complexContent>
      <xs:extension base="validator">
        <xs:attribute name="operator" type="compareOperator" use="required"></xs:attribute>
        <xs:attribute name="value" type="xs:string" use="required"></xs:attribute>
        <xs:attribute name="valueType" type="clrDataTypes"></xs:attribute>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="rangeValidator">
    <xs:complexContent>
      <xs:extension base="validator">
        <xs:attribute name="lowerBound" type="xs:string" use="required"></xs:attribute>
        <xs:attribute name="upperBound" type="xs:string" use="required"></xs:attribute>
        <xs:attribute name="valueType" type="clrDataTypes" use="required"></xs:attribute>
        <xs:attribute name="excludeBoundValues" type="xs:boolean"></xs:attribute>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="regexValidator">
    <xs:complexContent>
      <xs:extension base="validator">
        <xs:attribute name="pattern" type="xs:string" use="required"></xs:attribute>
        <xs:attribute name="ignoreCase" type="xs:boolean"></xs:attribute>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="requiredValidator">
    <xs:complexContent>
      <xs:extension base="validator">
        <xs:attribute name="trimWhiteSpaces" type="xs:boolean"></xs:attribute>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:simpleType name="memberAccess">
    <xs:restriction base="xs:string">
      <xs:enumeration value="Public"></xs:enumeration>
      <xs:enumeration value="Family"></xs:enumeration>
      <xs:enumeration value="Assembly"></xs:enumeration>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="memberInheritanceModifier">
    <xs:restriction base="xs:string">
      <xs:enumeration value="Virtual"></xs:enumeration>
      <xs:enumeration value="Abstract"></xs:enumeration>
      <xs:enumeration value="Override"></xs:enumeration>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="changeTracking">
    <xs:restriction base="xs:string">
      <xs:enumeration value="Auto"></xs:enumeration>
      <xs:enumeration value="Changing"></xs:enumeration>
      <xs:enumeration value="Changed"></xs:enumeration>
      <xs:enumeration value="Both"></xs:enumeration>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="typeInheritanceModifier">
    <xs:restriction base="xs:string">
      <xs:enumeration value="Abstract"></xs:enumeration>
      <xs:enumeration value="Final"></xs:enumeration>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="identifierCase">
    <xs:restriction base="xs:string">
      <xs:enumeration value="NoChange"></xs:enumeration>
      <xs:enumeration value="Pascal"></xs:enumeration>
      <xs:enumeration value="Camel"></xs:enumeration>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="clrPrimitiveTypes">
    <xs:restriction base="xs:string">
      <xs:enumeration value="string"></xs:enumeration>
      <xs:enumeration value="int"></xs:enumeration>
      <xs:enumeration value="bool"></xs:enumeration>
      <xs:enumeration value="long"></xs:enumeration>
      <xs:enumeration value="short"></xs:enumeration>
      <xs:enumeration value="byte"></xs:enumeration>
      <xs:enumeration value="double"></xs:enumeration>
      <xs:enumeration value="float"></xs:enumeration>
      <xs:enumeration value="decimal"></xs:enumeration>
      <xs:enumeration value="uint"></xs:enumeration>
      <xs:enumeration value="ushort"></xs:enumeration>
      <xs:enumeration value="ulong"></xs:enumeration>
      <xs:enumeration value="sbyte"></xs:enumeration>
      <xs:enumeration value="char"></xs:enumeration>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="clrCommonTypes">
    <xs:restriction base="xs:string">
      <xs:enumeration value="DateTime"></xs:enumeration>
      <xs:enumeration value="Guid"></xs:enumeration>
      <xs:enumeration value="TimeSpan"></xs:enumeration>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="clrDataTypes">
    <xs:union memberTypes="clrPrimitiveTypes clrCommonTypes xs:token"></xs:union>
  </xs:simpleType>

  <xs:complexType name="propertySerializationOptions">
    <xs:attribute name="name" type="xs:string"></xs:attribute>
    <xs:attribute name="mode">
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:enumeration value="Property"></xs:enumeration>
          <xs:enumeration value="Field"></xs:enumeration>
          <xs:enumeration value="None"></xs:enumeration>
        </xs:restriction>
      </xs:simpleType>
    </xs:attribute>
    <xs:attribute name="emitDefaultValue" type="xs:boolean" default="true"></xs:attribute>
  </xs:complexType>
                  
  <xs:complexType name="constantDeclaration">
    <xs:attribute name="type" >
      <xs:simpleType>
        <xs:union memberTypes="clrDataTypes">
          <xs:simpleType>
            <xs:restriction base="xs:string">
              <xs:enumeration value="Type"></xs:enumeration>
            </xs:restriction>
          </xs:simpleType>
        </xs:union>
      </xs:simpleType>
    </xs:attribute>
    <xs:attribute name="value" type="xs:string"></xs:attribute>
  </xs:complexType>

  <xs:complexType name="customAttribute">
    <xs:sequence>
      <xs:element name="param" minOccurs="0" maxOccurs="unbounded">
        <xs:complexType>
          <xs:complexContent>
            <xs:extension base="constantDeclaration">
              <xs:attribute name="name" type="xs:token"></xs:attribute>
              <xs:attribute name="casting"  default="implicit">
                <xs:simpleType>
                  <xs:restriction base="xs:string">
                    <xs:enumeration value="implicit"></xs:enumeration>
                    <xs:enumeration value="explicit"></xs:enumeration>
                  </xs:restriction>
                </xs:simpleType>
              </xs:attribute>
            </xs:extension>
          </xs:complexContent>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
    <xs:attribute name="type" use="required" type="xs:token"></xs:attribute>
  </xs:complexType>

  <xs:complexType name="customAttributes">
    <xs:sequence>
      <xs:element name="attribute" type="customAttribute" minOccurs="0" maxOccurs="unbounded"></xs:element>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="propertyMapping">
    <xs:attribute name="pk" type="xs:boolean"></xs:attribute>
    <xs:attribute name="column" type="xs:Name" ></xs:attribute>
    <xs:attribute name="dbtype" type="xs:string"></xs:attribute>
    <xs:attribute name="nullable" type="xs:boolean"></xs:attribute>
    <xs:attribute name="generated" type="xs:boolean"></xs:attribute>
    <xs:attribute name="timestamp" type="xs:boolean"></xs:attribute>
    <xs:attribute name="deferred" type="xs:boolean"></xs:attribute>
    <xs:attribute name="auto-sync">
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:enumeration value="Never"></xs:enumeration>
          <xs:enumeration value="OnInsert"></xs:enumeration>
          <xs:enumeration value="OnUpdate"></xs:enumeration>
          <xs:enumeration value="Always"></xs:enumeration>
        </xs:restriction>
      </xs:simpleType>
    </xs:attribute>
    <xs:attribute name="updateCheck">
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:enumeration value="Never"></xs:enumeration>
          <xs:enumeration value="WhenChanged"></xs:enumeration>
          <xs:enumeration value="Always"></xs:enumeration>
        </xs:restriction>
      </xs:simpleType>
    </xs:attribute>
    <xs:attribute name="discriminator" type="xs:boolean"></xs:attribute>
  </xs:complexType>

  <xs:complexType name="accessor">
    <xs:attribute name="name" type="xs:Name"></xs:attribute>
    <xs:attribute name="modifier" type="memberInheritanceModifier"></xs:attribute>
    <xs:attribute name="visible" type="xs:boolean"></xs:attribute>
    <xs:attributeGroup ref="mstns:memberAttributes"></xs:attributeGroup>
    <xs:attribute name="use" type="mstns:propertyUsage" default="Control"></xs:attribute>
  </xs:complexType>

  <xs:complexType name="association">
    <xs:all>
      <xs:element name="this" minOccurs="0" type="accessor"></xs:element>
      <xs:element name="parent" minOccurs="0" type="accessor"></xs:element>
      <xs:element name="keys">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="key" maxOccurs="unbounded">
              <xs:complexType>
                <xs:attribute name="this" type="xs:Name" use="required"></xs:attribute>
                <xs:attribute name="parent" type="xs:Name" use="required"></xs:attribute>
              </xs:complexType>
            </xs:element>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="serialization" type="propertySerializationOptions" minOccurs="0"></xs:element>
    </xs:all>
    <xs:attribute name="name" type="xs:Name"></xs:attribute>
    <xs:attribute name="parentType" type="xs:Name" use="required">
    </xs:attribute>
    <xs:attribute name="deleteRule">
      <xs:simpleType>
        <xs:union memberTypes="xs:Name">
          <xs:simpleType>
            <xs:restriction base="xs:string">
              <xs:enumeration value="Auto"></xs:enumeration>
              <xs:enumeration value="OnNull"></xs:enumeration>
              <xs:enumeration value="DontCare"></xs:enumeration>
            </xs:restriction>
          </xs:simpleType>
        </xs:union>
      </xs:simpleType>
    </xs:attribute>
    <xs:attribute name="cardinality">
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:enumeration value="OneToMany"></xs:enumeration>
          <xs:enumeration value="OneToOne"></xs:enumeration>
        </xs:restriction>
      </xs:simpleType>
    </xs:attribute>
    <xs:attribute name="pattern">
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:enumeration value="default"></xs:enumeration>
          <xs:enumeration value="IList"></xs:enumeration>
        </xs:restriction>
      </xs:simpleType>
    </xs:attribute>
  </xs:complexType>

  <xs:complexType name="mappingInheritanceOptions">
    <xs:attribute name="code" type="xs:token" use="required"></xs:attribute>
    <xs:attribute name="type" type="xs:Name" use="required"></xs:attribute>
    <xs:attribute name="isDefault" type="xs:boolean"></xs:attribute>
  </xs:complexType>

  <xs:complexType name="typeMapping">
    <xs:all>
      <xs:element name="associations" minOccurs="0">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="foreignKey" type="association" minOccurs="0" maxOccurs="unbounded"></xs:element>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="inheritances" minOccurs="0">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="inheritance" type="mappingInheritanceOptions" minOccurs="0" maxOccurs="unbounded"></xs:element>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:all>
    <xs:attribute name="table" type="xs:Name"></xs:attribute>
    <xs:attribute name="contextProperty" type="xs:string"></xs:attribute>
    <xs:attribute name="ignore" type="xs:boolean"></xs:attribute>
  </xs:complexType>

  <xs:element name="fileOptions">
    <xs:complexType>
      <xs:all>
        <xs:element name="mapping" minOccurs="0">
          <xs:complexType>
            <xs:attribute name="database" type="xs:string"></xs:attribute>
            <xs:attribute name="contextName" type="xs:string"></xs:attribute>
            <xs:attribute name="contextBaseType" type="xs:string"></xs:attribute>
            <xs:attribute name="provider" default="LinqToSql">
              <xs:simpleType>
                <xs:restriction base="xs:string">
                  <xs:enumeration value="LinqToSql"></xs:enumeration>
                </xs:restriction>
              </xs:simpleType>
            </xs:attribute>
            <xs:attribute name="connectionName" type="xs:string"></xs:attribute>
          </xs:complexType>
        </xs:element>
        <xs:element name="changeTracking" type="changeTrackingOptions" minOccurs="0"></xs:element>
        <xs:element name="baseTypes" type="baseTypes" minOccurs="0"></xs:element>
      </xs:all>
      <xs:attribute name="serializationEnabled" type="xs:boolean" default="true"></xs:attribute>
      <xs:attribute name="defaultNamespace" type="xs:string"></xs:attribute>
    </xs:complexType>
  </xs:element>


</xs:schema>
